package com.dalei.vds;

import java.lang.ref.WeakReference;
import java.util.List;

import com.dalei.vds.environment.SystemStatus;
import com.dalei.vds.service.SessionService;
import com.dalei.vds.settings.DeviceSettings;
import com.dalei.vds.settings.ServerSettings;
import com.dalei.vds.soap.LoginSoapImpl;
import com.dalei.vds.soap.RegisterDeviceSoapImpl;
import com.dalei.vds.soap.SessionSoapImpl;
import com.dalei.vds.telephone.Device;
import com.dalei.vdserver.shared.model.ErrorCode;
import com.dalei.vdserver.shared.soap.LoginSoap;
import com.dalei.vdserver.shared.soap.RegisterDeviceSoap;
import com.dalei.vdserver.shared.soap.SessionSoap;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;

public class LoginActivity extends Activity {

	public static final int REQUEST_SETTINGS = 0x00000000;

	private static final int MESSAGE_SHOW_DIALOG = 0x00000000;

	private static final int MESSAGE_DISMISS_DIALOG = 0x00000001;

	private static final int MESSAGE_SHOW_TOAST = 0x00000002;

	private static final int MESSAGE_LOAD_USERS = 0x00000003;

	private static final int MESSAGE_START_ACTIVITY = 0x00000004;

	private static final int MESSAGE_FINISH = 0x00000005;

	private static final int MESSAGE_START_SESSIONSERVICE = 0x00000006;

	private static final int MESSAGE_STOP_SESSIONSERVICE = 0x00000007;

	private Spinner userSpinner;

	private EditText passwordEdit;

	private Button loginBtn;

	private Button exitBtn;

	private ProgressDialog dialog;

	private Handler handler;

	private Intent sessionServiceIntent;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.login);

		userSpinner = (Spinner) findViewById(R.id.login_username);

		passwordEdit = (EditText) findViewById(R.id.login_password);

		loginBtn = (Button) findViewById(R.id.login_loginbtn);
		loginBtn.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
				// TODO Auto-generated method stub
				Thread thread = new LoginThread();
				thread.start();
			}
		});

		exitBtn = (Button) findViewById(R.id.login_exitbtn);
		exitBtn.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
				// TODO Auto-generated method stub
				finish();
			}
		});

		handler = new IncomingHandler(this);

		Thread thread = new OnLoadThread(this);
		thread.start();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.login_options_menu, menu);
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		Intent intent = null;
		switch (item.getItemId()) {
		case R.id.login_menuitem_refresh:
			Thread thread = new OnLoadThread(this);
			thread.start();
			break;

		case R.id.login_menuitem_settings:
			intent = new Intent();
			intent.setClass(this, SettingsActivity.class);
			startActivityForResult(intent, REQUEST_SETTINGS);
			break;

		case R.id.login_menuitem_about:
			break;

		case R.id.login_menuitem_exit:
			finish();
			break;

		default:
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		// super.onActivityResult(requestCode, resultCode, data);
		switch (requestCode) {
		case REQUEST_SETTINGS:
			Thread thread = new OnLoadThread(this);
			thread.start();
			break;

		default:
			break;
		}
	}

	private static class IncomingHandler extends Handler {

		private WeakReference<LoginActivity> reference;

		public IncomingHandler(LoginActivity activity) {
			// TODO Auto-generated constructor stub
			reference = new WeakReference<LoginActivity>(activity);
		}

		@Override
		@SuppressWarnings("unchecked")
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			super.handleMessage(msg);
			final LoginActivity activity = reference.get();

			switch (msg.what) {
			case MESSAGE_SHOW_DIALOG:
				activity.dialog = ProgressDialog.show(activity, null,
						activity.getString(R.string.waitting));
				break;

			case MESSAGE_DISMISS_DIALOG:
				activity.dialog.dismiss();
				break;

			case MESSAGE_SHOW_TOAST:
				Toast.makeText(activity, activity.getString(msg.arg1),
						Toast.LENGTH_SHORT).show();
				break;

			case MESSAGE_LOAD_USERS:
				List<String> users = (List<String>) msg.obj;
				ArrayAdapter<String> adapter = new ArrayAdapter<String>(
						activity, android.R.layout.simple_spinner_item, users);
				activity.userSpinner.setAdapter(adapter);
				break;

			case MESSAGE_START_ACTIVITY:
				Intent intent = (Intent) msg.obj;
				activity.startActivity(intent);
				break;

			case MESSAGE_FINISH:
				activity.finish();
				break;

			case MESSAGE_START_SESSIONSERVICE:
				activity.sessionServiceIntent = new Intent();
				activity.sessionServiceIntent.setClass(activity,
						SessionService.class);
				activity.startService(activity.sessionServiceIntent);
				break;

			case MESSAGE_STOP_SESSIONSERVICE:
				activity.stopService(activity.sessionServiceIntent);
				break;

			default:
				break;
			}
		}
	}

	private class OnLoadThread extends Thread {

		private Context context;

		public OnLoadThread(Context context) {
			// TODO Auto-generated constructor stub
			this.context = context;
		}

		@Override
		public void run() {
			// TODO Auto-generated method stub
			// super.run();
			handler.sendEmptyMessage(MESSAGE_SHOW_DIALOG);
			ServerSettings settings = new ServerSettings(context);
			int result = settings.debug();
			Message msg = null;
			switch (result) {

			case ServerSettings.NETWORK_NOT_AVAILABLE:
				handler.sendEmptyMessage(MESSAGE_DISMISS_DIALOG);
				msg = handler.obtainMessage();
				msg.what = MESSAGE_SHOW_TOAST;
				msg.arg1 = R.string.network_not_connected;
				handler.sendMessage(msg);
				break;

			case ServerSettings.SETTINGS_NOT_FOUND:
				handler.sendEmptyMessage(MESSAGE_DISMISS_DIALOG);
				msg = handler.obtainMessage();
				msg.what = MESSAGE_SHOW_TOAST;
				msg.arg1 = R.string.setting_not_found;
				handler.sendMessage(msg);
				break;

			case ServerSettings.INVALID_IP_ADDRESS:
				handler.sendEmptyMessage(MESSAGE_DISMISS_DIALOG);
				msg = handler.obtainMessage();
				msg.what = MESSAGE_SHOW_TOAST;
				msg.arg1 = R.string.invalid_ip_address;
				handler.sendMessage(msg);
				break;

			case ServerSettings.IP_ADDRESS_NOT_REACHABLE:
				handler.sendEmptyMessage(MESSAGE_DISMISS_DIALOG);
				msg = handler.obtainMessage();
				msg.what = MESSAGE_SHOW_TOAST;
				msg.arg1 = R.string.ip_address_not_reachadle;
				handler.sendMessage(msg);
				break;

			case ServerSettings.PORT_NOT_OPENED:
				handler.sendEmptyMessage(MESSAGE_DISMISS_DIALOG);
				msg = handler.obtainMessage();
				msg.what = MESSAGE_SHOW_TOAST;
				msg.arg1 = R.string.port_not_opened;
				handler.sendMessage(msg);
				break;

			case ServerSettings.INTERNAL_ERROR:
				handler.sendEmptyMessage(MESSAGE_DISMISS_DIALOG);
				msg = handler.obtainMessage();
				msg.what = MESSAGE_SHOW_TOAST;
				msg.arg1 = R.string.internal_error;
				handler.sendMessage(msg);
				break;

			case ServerSettings.WEB_SERVICE_NOT_AVAILABLE:
				handler.sendEmptyMessage(MESSAGE_DISMISS_DIALOG);
				msg = handler.obtainMessage();
				msg.what = MESSAGE_SHOW_TOAST;
				msg.arg1 = R.string.webservice_not_available;
				handler.sendMessage(msg);
				break;

			case ServerSettings.SUCCESS:
				LoginSoap soap = new LoginSoapImpl(context);
				msg = handler.obtainMessage();
				List<String> users = soap.getUsers();
				if (users != null) {
					msg.what = MESSAGE_LOAD_USERS;
					msg.obj = soap.getUsers();
				} else {
					msg.what = MESSAGE_SHOW_TOAST;
					msg.arg1 = R.string.load_users_failed;
				}
				handler.sendEmptyMessage(MESSAGE_DISMISS_DIALOG);
				handler.sendMessage(msg);
				break;

			default:
				break;
			}
		}
	}

	private class LoginThread extends Thread {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			// super.run();
			if (userSpinner.getSelectedItemPosition() >= 0) {
				handler.sendEmptyMessage(MESSAGE_SHOW_DIALOG);

				Device device = new Device(getApplicationContext());
				String imei = device.getIMEI();
				RegisterDeviceSoap registerDeviceSoap = new RegisterDeviceSoapImpl(
						getApplicationContext());
				int deviceId = registerDeviceSoap.containsDevice(imei);
				if (deviceId > 0) {
					DeviceSettings settings = new DeviceSettings(
							getApplicationContext());
					settings.setDeviceId(deviceId);
					SystemStatus.setDeviceId(deviceId);

					LoginSoap loginSoap = new LoginSoapImpl(
							getApplicationContext());
					String user = userSpinner.getSelectedItem().toString();
					String password = passwordEdit.getText().toString();
					int userId = loginSoap.validateUser(user, password);
					if (userId > 0) {
						SystemStatus.setUserId(userId);
						SystemStatus.setUserName(user);

						SessionSoap sessionSoap = new SessionSoapImpl(
								getApplicationContext());
						long timeout = sessionSoap.requesSession(deviceId,
								userId);
						if (timeout > 0) {
							SystemStatus.setSessionTimeout(timeout);
							SystemStatus.setLoggedOn(true);
							handler.sendEmptyMessage(MESSAGE_DISMISS_DIALOG);

							handler.sendEmptyMessage(MESSAGE_START_SESSIONSERVICE);

							Intent intent = new Intent();
							intent.setClass(LoginActivity.this,
									SelectorActivity.class);
							Message msg = handler.obtainMessage();
							msg.what = MESSAGE_START_ACTIVITY;
							msg.obj = intent;
							handler.sendMessage(msg);

							handler.sendEmptyMessage(MESSAGE_FINISH);
						} else {
							handler.sendEmptyMessage(MESSAGE_DISMISS_DIALOG);

							int code = (int) timeout;
							Message msg = null;
							switch (code) {
							case ErrorCode.UNKNOW_ERROR:
								msg = handler.obtainMessage();
								msg.what = MESSAGE_SHOW_TOAST;
								msg.arg1 = R.string.unknow_error;
								handler.sendMessage(msg);
								break;

							case ErrorCode.INTERNAL_ERROR:
								msg = handler.obtainMessage();
								msg.what = MESSAGE_SHOW_TOAST;
								msg.arg1 = R.string.internal_error;
								handler.sendMessage(msg);
								break;

							case ErrorCode.Session.DEVICE_NOT_REGISTERED:
								msg = handler.obtainMessage();
								msg.what = MESSAGE_SHOW_TOAST;
								msg.arg1 = R.string.device_not_registered;
								handler.sendMessage(msg);
								break;

							case ErrorCode.Session.USER_NOT_FOUND:
								msg = handler.obtainMessage();
								msg.what = MESSAGE_SHOW_TOAST;
								msg.arg1 = R.string.user_not_found;
								handler.sendMessage(msg);
								break;

							default:
								break;
							}
						}
					} else {
						handler.sendEmptyMessage(MESSAGE_DISMISS_DIALOG);

						int code = userId;
						Message msg = null;
						switch (code) {

						case ErrorCode.UNKNOW_ERROR:
							msg = handler.obtainMessage();
							msg.what = MESSAGE_SHOW_TOAST;
							msg.arg1 = R.string.unknow_error;
							handler.sendMessage(msg);
							break;

						case ErrorCode.INTERNAL_ERROR:
							msg = handler.obtainMessage();
							msg.what = MESSAGE_SHOW_TOAST;
							msg.arg1 = R.string.internal_error;
							handler.sendMessage(msg);
							break;

						case ErrorCode.Login.USER_NOT_FOUND:
							msg = handler.obtainMessage();
							msg.what = MESSAGE_SHOW_TOAST;
							msg.arg1 = R.string.user_not_found;
							handler.sendMessage(msg);
							break;

						case ErrorCode.Login.INVALID_PASSWORD:
							msg = handler.obtainMessage();
							msg.what = MESSAGE_SHOW_TOAST;
							msg.arg1 = R.string.invalid_password;
							handler.sendMessage(msg);
							break;

						case ErrorCode.Login.ALREADY_LOGGED_ON:
							msg = handler.obtainMessage();
							msg.what = MESSAGE_SHOW_TOAST;
							msg.arg1 = R.string.already_logged_on;
							handler.sendMessage(msg);
							break;

						default:
							break;
						}
					}
				} else {
					handler.sendEmptyMessage(MESSAGE_DISMISS_DIALOG);

					Message msg = handler.obtainMessage();
					msg.what = MESSAGE_SHOW_TOAST;
					msg.arg1 = R.string.device_not_registered;
					handler.sendMessage(msg);
				}
			} else {
				Message msg = handler.obtainMessage();
				msg.what = MESSAGE_SHOW_TOAST;
				msg.arg1 = R.string.user_not_selected;
				handler.sendMessage(msg);
			}
		}
	}
}
